#ifndef _PARGAME_EPOLL_H_
#define _PARGAME_EPOLL_H_

#include "pthread_pool.h"
#include "auser.h"

#include <iostream>
// #include <stdlib.h>
#include <memory.h>
// #include <unistd.h>
// #include <sys/types.h>
// #include <sys/time.h>
#include <arpa/inet.h>
// #include <netinet/in.h>
#include <sys/epoll.h>
// #include <string.h>
#include "config.h"


class Server;

//结构体



void func(void * arg)
{
    AUser *user = (AUser*)arg;
    user->Auser_bing();
}


class Server
{
    private:
        //服务器网络设置
        sockaddr_in m_Seraddr;
        socklen_t m_SeraddrLen;
        int socketFd;

        //线程池
        pthread_pool *pool;

        //在线人数
        int OLnum;      

        //状态
        bool Stop;


    public:
        //业务对象
        AUser *AU;

        //客户端连接
        sockaddr_in m_clientaddr;
        socklen_t m_clientaddrLen;
        int clientFd;

        //epoll的配置
        int epFd;
        struct epoll_event ev,evens[MAX_EVENTS];
        int nfds;

//函数
        Server(const char* ip,const char* port)
        : Stop(false)
        , OLnum(0)
        {
            AU = new AUser[1024];
            // if (argc < 0)
            // {
            //     perror("参数有误\n");
            //     return ;
            // }
            socketFd = socket(AF_INET,SOCK_STREAM,0);
            if (socketFd < 0)
            {
                perror("服务器套接字创建失败\n");
                return ;
            }

            m_Seraddr.sin_family = AF_INET;
            m_Seraddr.sin_addr.s_addr = inet_addr(ip);
            m_Seraddr.sin_port = htons(atoi(port));
            cout<<"ip"<<ip<<"  port"<<port<<endl;

            m_SeraddrLen = sizeof(m_Seraddr);

             //绑定
            if (bind(socketFd,(struct sockaddr*)&m_Seraddr,(socklen_t)sizeof(m_Seraddr)) < 0)
            {
                perror("绑定服务器网络失败\n");
                return ;
            }
            //端口复用
            int aport = 1;
            setsockopt(socketFd,SOL_SOCKET,SO_REUSEADDR,&aport,sizeof(aport));

            //epool初始化
            epFd = epoll_create1(0);

            pool = new pthread_pool;
            
        }
        
        ~Server()
        {
            if (socketFd > 0)
            {
                close(socketFd);
            }
            
            if (epFd > 0)
            {
                close(epFd);
            }

             delete pool;
             pool = nullptr;    

            delete []AU;
            AU = nullptr;      
        }

        int getclientFd()
        {
            return clientFd;
        }

        int getSocketFd()
        {
            return socketFd;
        }

        int getEpfd()
        {
            return epFd;
        }

        struct epoll_event* getEvens()
        {
            return evens;
        }
        //监听服务端
        int listenServer()
        {
            return (listen(socketFd,num));
        }

        //连接客户端
        int connetCilent()
        {
            return clientFd = (accept(socketFd,(struct sockaddr*)&m_clientaddr,&m_clientaddrLen));
        }

        //句柄加入epoll监听（默认监听读事件）
        int epollClient(int fd, int s = 0)
        {
            if (fd <= 0)
            {
                return -1;
            }

            if (s == 1)
            {
                ev.data.fd = fd;
                ev.events = EPOLLIN;
            }
            
            ev.data.fd = fd;
            ev.events = EPOLLIN | EPOLLET;

            return ((epoll_ctl(epFd,EPOLL_CTL_ADD,fd,&ev)));
        }

        //内核阻塞监听事件
        int Serverepoll()
        {
            return epoll_wait(epFd,evens,MAX_EVENTS,-1);
        }

        //移除epoll对某个句柄的监听
        int deteServerepoll(int fd)
        {
            return epoll_ctl(epFd,EPOLL_CTL_DEL,fd,&ev);
        }


//启动函数
        int Server_begin()
        {
            listenServer();
                       
            epollClient(socketFd,1);

            while (!Stop)
            {
                cout<<"准备等待"<<endl;
                nfds = Serverepoll();
                cout<<"事件数量"<<nfds<<endl;
                for (int i = 0; i < nfds; ++i)
                {
                    if (evens[i].data.fd == socketFd)
                    {
                        cout<<"客户端的连接建立"<<connetCilent()<<endl;
                        cout<<"clientfd "<<clientFd<<endl;
                        cout<<"客户端的事件监听"<<epollClient(clientFd)<<endl;
                    }
                    else
                    {
                        if (evens[i].events & EPOLLIN)
                        {

                            AU[evens[i].data.fd].UserSet(evens[i].data.fd,evens[i].events,epFd);
                            pool->addtask(func,AU+evens[i].data.fd);
                        }

                    }
                    
                }
               
            }
            

        }
};

#endif